package main

import (
	"fmt"
	"sort"
)

// Go语言中提供的映射关系容器是map，期内部使用 散列表(hash) 实现.
// map是一种无序的key:value数据结构，Go语言中的map是引用类型，必须初始化才能使用。

func main() {
	//初始化1: 声明时填充元素
	scoreMap := map[string]int{
		"zhangsan": 90,
		"lisi":     88,
	}
	fmt.Printf("Type of a: %T \n", scoreMap)
	fmt.Println(scoreMap)

	nilmap := map[int]string{}
	fmt.Println(nilmap)
	fmt.Printf("Type of a: %T \n", nilmap)

	//初始化2: make函数分配内存
	userAge := make(map[string]int, 2)
	fmt.Println(userAge)
	userAge["zhangsan"] = 16
	userAge["lisi"] = 15
	userAge["wangwu"] = 16
	fmt.Println(userAge)

	//判断map中键是否存在的特殊写法，格式: value, ok := map[key]
	_, iok := scoreMap["wangwu"]
	fmt.Println(iok)

	for key, val := range userAge {
		fmt.Printf("%s is age %d \n", key, val)
	}

	// 删除map中元素
	delete(userAge, "wangwu")
	fmt.Println(userAge)

	//按照指定顺序遍历map
	//(1)取出map中的所有key存入切片keys
	mapkeys := make([]string, 0, 10)
	for key := range userAge {
		mapkeys = append(mapkeys, key)
	}
	//(2)对切片进行排序
	fmt.Println(mapkeys)
	sort.Strings(mapkeys)
	//(3)按照排序后的key遍历map
	for _, val := range mapkeys {
		fmt.Printf("%s : %v \n", val, userAge[val])
	}

	// 元素为map类型的切片
	var mapSlice = make([]map[string]string, 3)
	for index, val := range mapSlice {
		fmt.Printf("index: %d  value: %v \n", index, val)
	}
	//对切片中的元素进行初始化并赋值
	mapSlice[0] = make(map[string]string, 3)
	mapSlice[0]["name"] = "小明"
	mapSlice[1] = make(map[string]string, 3)
	mapSlice[1]["age"] = "18"
	mapSlice[1]["city"] = "北京"
	fmt.Println(mapSlice)

	// 值为切片类型的map
	sliceMap := make(map[string][]string, 3)
	fmt.Println(sliceMap)
	key := "中国"
	val, ok := sliceMap[key]
	fmt.Println(val)
	if !ok {
		val = make([]string, 3)
	}
	val = append(val, "北京", "上海", "广州")
	sliceMap[key] = val
	fmt.Println(sliceMap)

	// 不管元素是map还是slice 在使用时需先初始化（make），在给元素赋值前还需先初始化（make）
	// map元素为map的二级元素为切片
	mapMap := make(map[string]map[string][]int)
	fmt.Println(mapMap)

}
